ShowTable of Contents
This article will go through the steps required to set up a test project to test custom XPages controls.
In this tutorial we will be using an example control project: com.example.xsp, but same steps can be applied to other controls.
To follow this tutorial, import the com.example.xsp project which can be found in the article's Attachments list.
Scaffolding the test project
In this section we will prepare the initial steps required to start testing our example control.
Create a new plugin named com.example.junit.tests and edit the Manifest to add dependancies on your com.example.xsp plugin.
Create a new package xsp.example.test and in the package, create a new Java Class, ExampleTestSuite.
Copy in the contents of the SampleTestSuite from the test framework project, rename to match your class.
It does not compile, as the Test and TestSuite classes cannot be resolved.
In the Manifest, add a plugin dependancy on org.junit (probably version 3.8.2) and com.ibm.xsp.test.framework.
Your ExampleTestSuite should now compile.
Right-click on ExampleTestSuite, Run As, JUnit Test. It might fail with:
java.lang.NoClassDefFoundError: org.eclipse.core.runtime.CoreException
If so, add a plugin dependancy on org.eclipse.core.runtime in the Manifest file.
Run ExampleTestSuite again (using the Run button in the toolbar). The first test fails with:
junit.framework.AssertionFailedError: No pages found to translate.
at com.ibm.xsp.test.framework.translator.GeneratePagesTest.testPagesNotChanged(GeneratePagesTest.java:102)
Ignore that test for a few moments.
Many tests will fail with the following error messages:
java.lang.RuntimeException: Not testing local xsp-configs, and not configured to test any library configs, so nothing to test.
at com.ibm.xsp.test.framework.TestProject.createRegistry(TestProject.java:102)
at com.ibm.xsp.test.framework.lifecycle.RegisteredDecodeTest.testDecodeRegisteredComponents(RegisteredDecodeTest.java:60)
You need to configure a config.properties file pointing to the library.
In your test plugin, create the package com.ibm.xsp.test.framework (exactly that, do not rename it to your plugin name.)
In that package, create a file config.properties with the contents:
# The XspLibrary.getLibraryId() value of the library
# whose contents should be tested, defaults to none,
# meaning that only local xsp-configs are loaded.
target.library=com.example.library
This file format is described in the config.properties file in the ..xsp.test.framework plugin.
Change the value in the file to match your library name.
In the Package Explorer view, click on the View Menu (a little down triangle to the right of the "Package Explorer" view name).
Select "Filters", and uncheck the checkbox beside ".* resources"
The .classpath and .project files in the plugin become visible.
Open the .classpath file, and re-order the contents so the src folder entry is before the requiredPlugins entry, like:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Re-run the test suite. If the 2nd test is still giving the same error you may have an issue with your classpath dependancy ordering (verify by debugging to see that it is loading the config.properties in the .xsp.test plugin).
The console contains the following in red (printed to System.err):
13-May-2013 11:04:10 com.ibm.xsp.library.ConfigFileMaintainerImpl createPrivateRegistry
WARNING: CLFAD0128W: The registry for the application ...workspace\xsp.example.junit.test cannot depend on the library with id com.ibm.xsp.domino.library, because there is no such library.
13-May-2013 11:04:10 com.ibm.xsp.library.ConfigFileMaintainerImpl createPrivateRegistry
WARNING: CLFAD0128W: The registry for the application ...workspace\xsp.example.junit.test cannot depend on the library with id com.ibm.xsp.extsn.library, because there is no such library.
13-May-2013 11:04:10 com.ibm.xsp.library.ConfigFileMaintainerImpl createPrivateRegistry
WARNING: CLFAD0128W: The registry for the application ...workspace\xsp.example.junit.test cannot depend on the library with id com.ibm.xsp.designer.library, because there is no such library.
13-May-2013 11:04:10 com.ibm.xsp.library.ConfigFileMaintainerImpl createPrivateRegistry
WARNING: CLFAD0128W: The registry for the application ...workspace\xsp.example.junit.test cannot depend on the library with id com.ibm.xsp.rcp.library, because there is no such library.
The project has not been defined with a list of dependancy libraries, so it is attempting to depend on the XPages runtime libraries, but none of those plugins are listed in the Manifest file.
In the Manifest, add dependancies on the XPages runtime plugins:
com.ibm.xsp.core
com.ibm.xsp.extsn
com.ibm.xsp.designer
com.ibm.xsp.domino
com.ibm.xsp.rcp
com.ibm.xsp.theme.oneuiv302
If the 2nd test fails with:
com.ibm.xsp.test.framework.lifecycle.RegisteredDecodeTest
testDecodeRegisteredComponents(com.ibm.xsp.test.framework.lifecycle.RegisteredDecodeTest)
com.ibm.xsp.FacesExceptionEx: java.lang.NoClassDefFoundError: lotus/domino/NotesException
at com.ibm.xsp.config.CLBootStrap.initContext(CLBootStrap.java:89)
at com.ibm.xsp.config.BootStrap.init(BootStrap.java:82)
at com.ibm.xsp.test.framework.TestProject.bootstrap(TestProject.java:405)
at com.ibm.xsp.test.framework.TestProject.createRequest(TestProject.java:368)
at com.ibm.xsp.test.framework.TestProject.createFacesContext(TestProject.java:340)
at com.ibm.xsp.test.framework.lifecycle.RegisteredDecodeTest.testDecodeRegisteredComponents(RegisteredDecodeTest.java:77)
Caused by: java.lang.NoClassDefFoundError: lotus/domino/NotesException
Edit your JRE configuration to add the Notes.jar and njempcl.jar as follows:
In eclipse, menu, Window, Preferences, Java, Installed JREs, select the JRE and click Edit.
Add External JARs, browse to jvm\lib\ext\ in your Notes directory and select both .jars:
njempcl.jar and
Notes.jar
OK, Finish, OK. Wait for it to finish compiling, rerun the JUnit tests.
If one of the tests fail with:
com.ibm.xsp.FacesExceptionEx: java.lang.NoClassDefFoundError: com.ibm.designer.domino.napi.NotesAPIException
.........
Caused by: java.lang.NoClassDefFoundError: com.ibm.designer.domino.napi.NotesAPIException
In the Manifest, add a dependancy on com.ibm.domino.napi and rerun the tests..
If the 2nd test now fails with:
java.lang.NoClassDefFoundError: com/ibm/designer/runtime/domino/adapter/util/PageNotFoundException
In the Mainfest add a dependancy on com.ibm.domino.xsp.adapter and rerun the tests.
The 2nd test passes, but the console may still contain:
java.lang.NoClassDefFoundError: com/ibm/designer/runtime/domino/bootstrap/BootstrapEnvironment
at com.ibm.domino.xsp.module.nsf.platform.Factory.createPlatform(Factory.java:34)
In the Mainfest add a dependancy on com.ibm.domino.xsp.bootstrap
The Console still contains:
java.lang.UnsatisfiedLinkError: no nlsxbe in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
You can ignore that.
Errors and failures
In this section we will address many possible failures and errors that may be encountered when running the test suite.
BaseGeneratePagesTest
com.ibm.xsp.test.framework.translator.BaseGeneratePagesTest
testPagesNotChanged(com.ibm.xsp.test.framework.translator.BaseGeneratePagesTest)
junit.framework.AssertionFailedError: No pages found to translate.
at com.ibm.xsp.test.framework.translator.GeneratePagesTest.testPagesNotChanged(GeneratePagesTest.java:102)
That fail indicates that there are no test .xsp files within the test project.
At the project root, create a folder named pages (just a convention - it will actually search through all folders),
And create a example.xsp file, containing a simple XPage that uses your control, like:
Re-run the test suite. Now the test fails with an unknown namespace problem:
com.ibm.xsp.test.framework.translator.BaseGeneratePagesTest
testPagesNotChanged(com.ibm.xsp.test.framework.translator.BaseGeneratePagesTest)
junit.framework.AssertionFailedError: 1 fail(s). :
[0] # /pages/simpleTestOfExampleControl.xsp Problem translating file: Unknown component namespace for the tag eg:exampleControl, with the namespace http://example.com/xsp/control.
at com.ibm.xsp.test.framework.translator.GeneratePagesTest.testPagesNotChanged(GeneratePagesTest.java:200)
That problem is occurring because the java file generator does not know that this test project depends on the library (the config.properties dependancy above is only used by the tests, it is not passed to the design-time code in the java file generator).
Configure an xsp.properties file listing the libraries this test project depends on (equivalent to changing an application's Application Properties, Advanced tab, XPages libraries list):
At the project root, create a folder WEB-INF
And create xsp.properties file with the contents (the ..xsp.core library is always required):
xsp.library.depends=\
com.ibm.xsp.core.library,\
com.ibm.xsp.extsn.library,\
com.ibm.xsp.designer.library,\
com.ibm.xsp.domino.library,\
com.example.library
Side Note
The current (9.0.0) designer release has a known issue which hinders the creation of a xsp.properties file.
Tho avoid this, create ysp.properties file instead and rename it after pasting in the content.
The issue has been addressed and will be fixed with the next release.
Now re-run the test suite.
It now fails with:
com.ibm.xsp.test.framework.translator.BaseGeneratePagesTest
testPagesNotChanged(com.ibm.xsp.test.framework.translator.BaseGeneratePagesTest)
junit.framework.AssertionFailedError: 1 fail(s). :
[0] * /pages/simpleTestOfExampleControl.xsp File generated, refresh the project.
at com.ibm.xsp.test.framework.translator.GeneratePagesTest.testPagesNotChanged(GeneratePagesTest.java:200)
That BaseGeneratePagesTest is not really a unit test, it is a utility class to generate the .java file corresponding to each .xsp file.
When running the test suite, you must first generate the .java files, then refresh the project so that eclipse detects and compiles the .java files to .class files, then run the main test suite.
The BaseGeneratePagesTest does actually function as a unit test, to remind you that you have forgotten to generate the .java files, so the .class files will not be available and any tests that attempt to load and render the .xsp pages will fail.
It is best to make a subclass of BaseGeneratePagesTest, to make it easier to run .java file generation outside of running the entire test suite.
XPages xsp page to Java generation
Create a ..translator (in our case it is xsp.example.test.translator) package in your test project (The package is .translator because the code that generates a .java file from an .xsp file is called a translator --- translation from .xps to .java).
Create a class ExampleGeneratePagesTest extending BaseGeneratePagesTest.
Right-click on that class, Run As, JUnit test.
Refresh the project, you will see a new gen/ folder created at the project root.
You should configure that to be treated as a Java Source Folder, so the contents are compiled.
Right-click on the project, Properties, Java Build Path, first tab(Source), Add Folder, select the gen folder, OK, OK.
You will see the gen/ source folder contains a translation.properties file, and a xsp.pages package with one .java file per .xsp file.
If you create subfolders under your pages/ folder, there will be subpackages under that package.
Run the *GeneratePages*(in our case it is ExampleGeneratePagesTest) test, refresh the project, run the test suite.
The first test will pass.
BaseViewSerializeTest
Once you have added the .xsp file for the previous test, there will be a new failure:
com.ibm.xsp.test.framework.serialize.BaseViewSerializeTest
testAllViews(com.ibm.xsp.test.framework.serialize.BaseViewSerializeTest)
junit.framework.AssertionFailedError: 1 fail(s). :
Failed on view [0] /pages/simpleTestOfExampleControl.xsp with: /pages/simpleTestOfExampleControl UIViewRootEx2.getFacetsAndChildren()[0] get method should not return a UIComponent
at com.ibm.xsp.test.framework.serialize.ViewSerializeTest.testAllViews(ViewSerializeTest.java:151)
That test creates the control tree for each .xsp file, serializes and restores the tree and verifies the restored control tree matches the original tree.
Create a new ..serialize(in our case it is xsp.example.test.serialize) package, and create an ExampleViewSerializeTest, extending from BaseViewSerializeTest.
In ExampleTestSuite, change the reference form ExampleViewSerializeTest to BaseViewSerializeTest to refer to the new test.
Edit the new test to add the method:
@Override
protected Object[][] getCompareSkips() {
Object[][] skips = super.getCompareSkips();
return skips;
}
Rerun the test suite.
The BaseViewSerializeTest will have disappeared and the its replacement ExampleViewSerializeTest should have passed.
BaseNamingConventionTest
This test is failing:
com.ibm.xsp.test.framework.registry.BaseNamingConventionTest
testNamingConventions(com.ibm.xsp.test.framework.registry.BaseNamingConventionTest)
java.lang.RuntimeException: Prefix not found in config.properties, like: NamingConvention.package.prefix=com.example.foo
at com.ibm.xsp.test.framework.registry.NamingConventionTest.testNamingConventions(NamingConventionTest.java:91)
In the test project config.properties file add the lines:
# Package name and component-type prefix, like "com.ibm.xsp" or
# "com.ibm.xsp.extlib", used in the NamingConventionTest
#NamingConvention.package.prefix=
NamingConvention.package.prefix=com.example
Rerun the test suite.
The test still fails because the control does not match the naming convention --- it may be that a test subclass is needed to change the convention tested.
The build.properties file in the test project contains:
Open the file, click on the warning, choose the action "Add gen/ to the source.. build entry"
The first line becomes:
Run the test suite.
There are still fails.
Create a ..registry(in our case it is xsp.example.test.registry) package
Create a Java Class in that package named ExampleNamingConventionTest that extends BaseNamingConventionTest
Copy the following contents to the newly created Java Class:
@Override
protected boolean isRequireControlSubpackageName() {
return false;
}
@Override
protected String[] getExpectedPrefixes() {
String[] expectedPrefixes = super.getExpectedPrefixes();
// [0] package-name prefix
//"com.ibm.xsp",
//expectedPrefixes[0] = "com.ibm.xsp.extlib";
// [1] abstract component package-name suffix: usually ".component"
//".component",
expectedPrefixes[1] = ".component.+";
// [2] tag component package-name suffix: usually ".component" or "component.xp."
//".component.xp",
expectedPrefixes[2] = ".component";
[4] tag component short java-class prefix: usually "Xsp"
"Xsp",
expectedPrefixes[4] = "";
// // [5] abstract component short java-class suffix: possibly "Ex" or "Ex2"
// expectedPrefixes[5] = "Base";
// [7] abstract component-type short-name prefix: usually "UI"
//"UI",
expectedPrefixes[7] = "";
return expectedPrefixes;
}
Update ExampleTestSuite to use ExampleNamingConventionTest instead of BaseNamingConventionTest.
Re-run the tests.
The BaseNamingConventionTest will have disappeared and the its replacement ExampleNamingConventionTest should have passed.
BaseSuiteSetupTest
There is another failure:
java.lang.UnsupportedOperationException: getTestedSuiteName() method must be overridden in a subclass.
As the error message suggests, it must be overridden in a subclass.
Create a package ..setup (in our case it is xsp.example.test.setup).
Create new Java Class ExampleSuiteSetupTest that extends BaseSuiteSetupTest with the following methods implemented:
@Override
protected long getTestedSuiteVersion() {
return ExampleTestSuite.SUITE_VERSION;
}
@Override
protected String getTestedSuiteName() {
return "ExampleTestSuite";
}
The SUITE_VERSION value will be present in your test suite from when you copied the contents of the Sample TestSuite.
Update ExampleTestSuite to use ExampleSuiteSetupTest instead of BaseSuiteSetupTest.
Re-run the tests.
The BaseSuiteSetupTest will have disappeared and the its replacementExampleSuiteSetupTest should have passed.
The purpose of that test is to ensure that your test project is up to date with the latest version of the ..test.framework project.
So when a new test is added to the test framework's SampleTestSuite, the version number there is incremented, and this test will fail, to indicate that the new test should be copied to your test project's test suite.
The SampleTestSuite is written with many comments to make it easier to do a file comparison or diff to see exactly which new tests have been added.
You would compare the updated SampleTestSuite to the TestSuite in your test project.
BaseGroupReuseTest
This test fails can fail with:
junit.framework.AssertionFailedError: 1 fail(s). :
META-INF/exampleControl.xsp-config eg:exampleControl title Should reuse <group-type-ref> for an existing control group: com.ibm.xsp.group.core.prop.title
Even though this is failing, it is not required for the control to function properly. For the demonstration purpose, we are going to add a skip to JUnit tests.
The reason that the test is complaining is because there is a reusable
in the XPages runtime
that can sometimes be used for defining a "title" property using the shorter syntax in the xsp-config file,
instead of the longer syntax. See the XPages configuration file format document for details.
The mentioned title group can be reused if your title property is exactly the same as that group's title property.
Link to XPages configuration file format
Copy the fail message from the JUnit results window into a text file. In our case the message is:
META-INF/exampleControl.xsp-config eg:exampleControl title Should reuse <group-type-ref> for an existing control group: com.ibm.xsp.group.core.prop.title
If it does not exist yet, create a package ..registry(in our case it is xsp.example.test.registry)
Create a Java Class ExampleGroupReuseTest in the newly created package that extends BaseGroupReuseTest with the following contents:
private String[] skips = new String[]{
"META-INF/exampleControl.xsp-config eg:exampleControl title Should reuse <group-type-ref> for an existing control group: com.ibm.xsp.group.core.prop.title"
};
@Override
protected String[] getSkipFails() {
return skips;
}
The skips variable of String[] type contains error messages that we want to ignore and make the test pass.
Update ExampleTestSuite to use ExampleGroupReuseTest instead of BaseGroupReuseTest.
Re-run the tests.
The BaseGroupReuseTest will have disappeared and the its replacement ExampleGroupReuseTest should have passed.
BaseLabelsLocalizableTest
A failure will appear:
junit.framework.AssertionFailedError: 1 fail(s). :
META-INF/exampleControl.xsp-config eg:exampleControl.mainHeader unexpected localizable prop
This test fails because the property name is not recognized as part of the localizable property list.
We are going to extend that list by overriding the Base class.
The localizable property list is a list of property names that should always be translatable, in every control where they occur. If the property name should only be localizable in this individual control, not in all controls, then instead of adding to the list, you would add a tag to the xsp-config file for that property, indicating that it is indeed intended to be localizable.
In the property definition you would add the tag in roughly this syntax:
true>localizable-text>>.
Adding to the always localizable property list:
If it doe snot exist yet, create a package ..registry(in our case it is xsp.example.test.registry)
Create a Java Class ExampleLabelsLocalizableTest in the newly created package that extends BaseLabelsLocalizableTest with the following contents:
// Custom mainTitle property to localize
private String[] extendListLocalizableNames = new String[]{
"mainHeader"
};
protected List<String> getCommonLocalizableNames() {
List<String> commonListLocalizableNames=super.getCommonLocalizableNames();
List<String> combinedList = new ArrayList<String>();
combinedList.addAll(Arrays.asList((String[])commonListLocalizableNames.toArray()));
combinedList.addAll(Arrays.asList(extendListLocalizableNames));
return combinedList;
}
The code above specifies a new array with list of properties that should be localizable(in our case it is just one - mainHeader).
getCommonLocalizableName method calls a super-class method to get the predefined list and appends our own. It then returns the new list.
Update ExampleTestSuite to use ExampleLabelsLocalizableTest instead of BaseLabelsLocalizableTest.
Re-run the tests.
The BaseLabelsLocalizableTest will have disappeared and the its replacement ExampleLabelsLocalizableTest should have passed.
BaseNamingConventionErrorTest
This is linked to the NamingConventionTest discussed above, and that it has a subset of the problems reported by that test, specifically this test only complains about ERROR severity issues, while the other test will also complain about WARNING issues and INFO issues.
junit.framework.AssertionFailedError: 2 fail(s). :
META-INF/exampleControl.xsp-config Missing required <control-subpackage-name> in config file, inferring subpackage []
META-INF/exampleControl.xsp-config/eg:exampleControl [Rule3] Bad component-class short name ExampleControl does not begin with Xsp
If it does not exist yet, create a package ..registry(in our case it is xsp.example.test.registry)
Create a Java Class ExampleNamingConventionErrorTest in the newly created package that extends ExampleNamingConventionTest (which you created above) with the following contents:
@Override
public String getDescription() {
return super.getDescription() +" [ERROR severity only]";
}
@Override
protected int getRuleSeverityLevelCutoff() {
// only show Errors, not Warning and Info
return SEV_ERROR;
}
Update ExampleTestSuite to use ExampleNamingConventionErrorTest instead of BaseNamingConventionErrorTest.
Re-run the tests.
The BaseNamingConventionErrorTest will have disappeared and the its replacement ExampleLabelsLocalizableTest should have passed.
BaseControlCategoryKnownTest
The control category is used in Designer in the Controls palette; you drag-and-drop the controls from the palette onto the page.
The category corresponds to the drawers or sections in that palette; like Core Controls and Container Controls.
For your library you would probably invent a new control category, and use that category for all controls in your library.
junit.framework.AssertionFailedError: 1 fail(s). :
META-INF/exampleControl.xsp-config eg:exampleControl unknown category: Example
We are going to add a new known category.
If it does not exist yet, create a package ..registry.annotate(in our case it is xsp.example.test.registry.annotate)
Create a Java Class ExampleControlCategoryKnownTest in the newly created package that extends BaseControlCategoryKnownTest(which you created above) with the following contents:
private String[] extendControlCategoryNames = new String[]{
"Example",
};
@Override
protected String[] getKnownControlCategories() {
String[] existing = super.getKnownControlCategories();
String[] updated = XspTestUtil.concat(existing, extendControlCategoryNames);
return updated;
}
Update ExampleTestSuite to use ExampleControlCategoryKnownTest instead of BaseControlCategoryKnownTest.
Re-run the tests.
The BaseControlCategoryKnownTest will have disappeared and the its replacement ExampleControlCategoryKnownTest should have passed.
BaseRoleAccessibilityTest
One failure can occur here:
junit.framework.AssertionFailedError: 1 fail(s). :
META-INF/exampleControl.xsp-config eg:exampleControl Expected role property for accessibility does not exist.
Again, in this case we are adding skips to make this test pass.
Copy the fail message from the JUnit results window into a text file. In our case the message is:
META-INF/exampleControl.xsp-config eg:exampleControl Expected role property for accessibility does not exist.
If it does not exist yet, create a package ..registry.annotate(in our case it is xsp.example.test.registry.annotate)
Create a Java Class ExampleRoleAccessibilityTest in the newly created package that extends BaseRoleAccessibilityTest with the following contents:
private String[] skips = new String[]{
"META-INF/exampleControl.xsp-config eg:exampleControl Expected role property for accessibility does not exist."
};
@Override
protected String[] getSkipFails() {
return skips;
}
As previously, the skips variable that gets returned contains messages that need to be skipped.
Update ExampleTestSuite to use ExampleRoleAccessibilityTest instead of BaseRoleAccessibilityTest.
Re-run the tests.
The BaseRoleAccessibilityTest will have disappeared and the its replacement ExampleRoleAccessibilityTest should have passed.
BaseSinceVersionsSetTest - Versioning
The versioning test can fail with:
junit.framework.AssertionFailedError: 1 fail(s). <since> version mismatch:
META-INF/exampleControl.xsp-config eg:exampleControl bad since version. Expected <since>null(probably)<, was <since>1.0.0<
junit.framework.AssertionFailedError: 1 fail(s). Known tags list not available. Please override getSinceVersionLists() and list these tags.:
tag eg:exampleControl has new props: 2 {mainHeader, title}
If does not exist yet, create a package ..version(in our case it is xsp.example.test.version)
Create a Java Class ExampleSinceVersionLists with the following contents:
public static List<SinceVersionList> getSinceVersionLists(){
List<SinceVersionList> list = new ArrayList<SinceVersionList>();
list.add(new Example100List());
return list;
}
public static class Example100List implements SinceVersionList {
private Object[][] tagsAndProps = new Object[][]{
// new Object[]{"prefixedTagName", newTagThisVersion, new String[]{
// "propName",
// "propName",
// }},
new Object[]{"eg:exampleControl", true, new String[]{
"mainHeader",
"title",
}},
};
private String[] skips = new String[]{
};
public Object[][] tagsAndProps() {
return tagsAndProps;
}
public String sinceVersion() {
return "1.0.0";
}
public String[] skips() {
return skips;
}
}
Create a Java Class ExampleSinceVersionsSetTest in the newly created package that extends BaseSinceVersionsSetTest with the following contents:
@Override
protected List<SinceVersionList> getSinceVersionLists() {
List<SinceVersionList> list = super.getSinceVersionLists();
list.addAll(ExampleSinceVersionLists.getSinceVersionLists());
return list;
}
Update ExampleTestSuite to use ExampleSinceVersionsSetTest instead of BaseSinceVersionsSetTest
Re-run the tests. It should pass.
This is needed because of how XPages handles different versions of plugins. Please read this Wiki article first:
XPages Page Versions
Also read this wiki article:
XPages Library Versioning
A library can contain multiple tags corresponding to a control(in our case it is eg:exampleControl)
Each tag can have multiple properties (in our case it is mainHeader and title).
For each new version a new class similar to the Example100List should be created (subsequent would probably be Example101List).
Each such class should include the newly added tags/properties only --- it must not include all properties available, only new ones.
For each such class the sinceVersion method must be updated to return the new version tagsAndProps variable must be updated with the newly added tags/properties.
The ExamplePrintTagNamesAndProps tool can be used to generate the updated tagsAndProps variable, provided that the new xsp-config definitions of the tags and properties have the correct 1.0.1> tag.
Once such class is created, add a reference to it in the getSinceVersionLists.
BaseReflectionSerializeTest and BaseRegisteredSerializationTest
junit.framework.AssertionFailedError: 1 fail(s). :
META-INF/exampleControl.xsp-config eg:exampleControl Control class not known to registry: UIViewRootEx2
Open config.properties located in com.ibm.xsp.test.framework. Append the following lines to the file:
# Extra libraries whose xsp-config files should be loaded
# when creating a registry
extra.library.depends.designtime.nonapplication=\
com.ibm.xsp.extsn.library
Re-run the tests. It should pass now.
The error message suggests that the component depends on the com.ibm.xsp.extsn.library plugin.
This is design time plugin dependencies that are different from runtime.
In future, if your plugin depends on other library plugins this is the place where it needs to be added.
target.library property points to your own library plugin and hence is not required to be added to the extra library dependency list.
It is recommended to create a separate test project for each library plugin, but If a set a of plugins need to be tested from
one test project it should be added to the extra library dependency list. Unless your target library already
has a dependency on a second library plugin.
BaseRenderThemeControlTest
This test can fail, depending on your configuration, in either or both of the following issues.
Domino server install location
In some cases this test fails because the Domino server is installed in different location than expected.
java.lang.RuntimeException: Cannot find any of the suggested Domino install folders: c:\Domino,C:\Program Files\IBM\Lotus\Domino,C:\Program Files (x86)\IBM\Lotus\Domino,/opt/ibm/lotus,/opt/lotus
If this is the case, one can change or add the Domino server install location in the detectDominoInstallLocation method in the TestProject.java file of the com.ibm.xsp.test.framework project.
Just update the defaultDominoSearchLocations array of strings:
public static File detectDominoInstallLocation(AbstractXspTest test){
if( null != test.getTestLocalVars().get("dominoInstallLocation") ){
throw new RuntimeException("dominoInstallLocation already exists");
}
String[] dominoSearchLocations;
String[] defaultDominoSearchLocations = new String[]{
"c:\\Domino",
"C:\\Program Files\\IBM\\Lotus\\Domino",
"C:\\Program Files (x86)\\IBM\\Lotus\\Domino",
"/opt/ibm/lotus", /*yeah, the folder name is lotus*/
"/opt/lotus",
};
Theme files
This will fail with:
junit.framework.AssertionFailedError: 11 fail(s). :
Problem setting theme to oneuiv3.0.2, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_blue, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_gen2, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_gold, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_green, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_onyx, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_orange, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_pink, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_purple, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_red, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_silver, current theme is: <empty>
The failure is a known issue. The XPages team is working to fix this. Please ignore this failure.
To have a fully passing test project, follow and adapt the steps described in the next section.
Green Test Suite
Green test suite is used as a temporary solution to make the failing tests pass.
For example, when there is a set of known issues and there is a need to track any new regression.
Instead of having a list with the issues you add them to the green test suite's junit-results.txt text file.
In the ..test package(in our case it is xsp.example.test) create a Java Class GreenExampleTestSuite that extends TestSuite with the following contents:
public static Test suite() {
ExampleTestSuite mainSuite = new ExampleTestSuite();
List<Class<? testClasses = ExampleTestSuite.getTestClassList();
// if necessary replace a class with a green subclass (that will always pass), like so:
// testClasses.set(testClasses.indexOf(RegisteredDecodeTest.class), GreenRegisteredDecodeTest.class);
TestClassList.addAll(mainSuite, testClasses);
GreenExampleTestSuite greenSuite = new GreenExampleTestSuite();
greenSuite.addTest(new SkipFileTestSetup(mainSuite,"junit-results.txt"));
greenSuite.addTestSuite(SkipFileUsedTest.class);
return greenSuite;
}
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
}
In the suite() method we are are creating our main test suite class (in our case it is ExampleTestSuite) and loading all the test cases.
Then we are creating our Green test suite class (GreenExampleTestSuite) and providing a text file that will contain fail messages that we will need to skip.
In the root of your test project create a text file junit-results.txt. It is best to add these three lines at the top of the file:
JUnit results, running against Notes 9.0.0
Test ran 2013-05-13 10:00
Lines in file: 59
Where in the first line you describe against which version the test suite was ran.
Lines in file: is just for tracking purpose to compare with previous results in case new issues were introduced.
Copy the failure list by right-clicking on the junit tests window and select Copy Failure List
Add an empty new line after those three lines. Again on a new line paste the failure list. The resulting text file should look something like this:
JUnit results, running against Notes 9.0.0
Test ran 2013-05-13 10:01
Lines in file: 42
ExampleTestSuite
com.ibm.xsp.test.framework.SampleTestSuite
com.ibm.xsp.test.framework.render.BaseRenderThemeControlTest
testRenderControlsInThemes(com.ibm.xsp.test.framework.render.BaseRenderThemeControlTest)
junit.framework.AssertionFailedError: 11 fail(s). :
Problem setting theme to oneuiv3.0.2, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_blue, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_gen2, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_gold, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_green, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_onyx, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_orange, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_pink, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_purple, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_red, current theme is: <empty>
Problem setting theme to oneuiv3.0.2_silver, current theme is: <empty>
at junit.framework.Assert.fail(Assert.java:47)
at com.ibm.xsp.test.framework.render.RenderThemeControlTest.testRenderControlsInThemes(RenderThemeControlTest.java:238)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:230)
at junit.framework.TestSuite.run(TestSuite.java:225)
at junit.framework.TestSuite.runTest(TestSuite.java:230)
at junit.framework.TestSuite.run(TestSuite.java:225)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
In general, the first three lines are not required but may be used for the reasons explained previously.
Now, if we run the green test suite all the failures that are present in the junit-results.txt should pass.
Actually, those issues ignored by the Green suite, but will still fail when using the main suite.
You would continue fixing the problems reported by the main suite, by looking at each test superclass to investigate what each test does, and trying to figure out how to change the control to fix the problem, or deciding that you do not need to fix the issue, and adding a skip method to your own subclass.